/* Scene.h  -- scene representation 

Copyright (C) 2010 Gabriel Alises Cano, Javier Angulo Lucerón

This file is part of Computer Graphics : Final Project 09-10.

Computer Graphics : Final Project 09-10 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Computer Graphics : Final Project 09-10 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Computer Graphics : Final Project 09-10.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef SCENE_H
#define SCENE_H

#include <GL/gl.h>
#include <vector>
#include <iostream>

#include "Object3D.h"
#include "Camera.h"
#include "Types.h"

//#include "importar.h"

using namespace std;

class Scene {

	private :

		/** Objects of the scene
		** Index starting in 0 */
		vector<Object3D *> objects;
		/** Camera */
		Camera *cam;
		/** Mode of operation (normal, selection or edition) */
		TState state;
                
	public :

		Scene (Camera *cam);
		~Scene ();

		/** \brief Get the Camera*/
		Camera *get_cam ();
		/** \brief Get the objects */
		vector<Object3D *> get_objects ();
		/** \brief Set the operation mode */
		void set_state (TState st);
		/** \brief Get the operation mode */
		TState get_state ();
		
		/* Selection issues */
		/*import orj*/
		void importar(char *ruta);
		/** \brief Add a new object to scene
		* \param o : new object
		* \return : index of the new object */
		GLuint add_object (Object3D *o);
		/** \brief Delete object n from scene
		* \param n : index of the object to delete */
		void delete_object (GLuint n);
		/** \brief Select all objects
		* \return number of objects selected */
		GLuint select_all ();
		/** \brief Deselect all objects */
		void deselect_all ();
		/** \brief Make inverse selection
		* \return number of objects selected */
		GLuint select_inverse ();
		/** \brief Select n'th object 
		* \param n : index of the object in vector
		* \return : 0 if exists, 1 if doesnt */
		GLuint select_object (GLuint n);        
		/** \brief Deselect n'th object
		* \param n : index of the object in vector */
		void deselect_object (GLuint n);                
		/** \brief State of i-object
 		 *  \return State of the object */
		TState get_state_i (GLuint n);
		/** \brief Edit a face of an object 
 		 *  \param n_obj : number of the object
 		 *  \param n_triang : number of the triang of the object
 		 *  \return : pointer to the n_triang'th triangle  */	
		Triangle * edit_face (GLuint n_obj, GLuint n_triang);
		/** \brief Get number of selected objects */
		GLuint get_n_selected_objects ();	
		/** \brief Get the selected objects indexes */
		vector<GLuint> get_selected_objects ();	
			
		/* Editing issues */

		/** \brief Edit n'th object
 		* \param n : index of the object */ 
		GLuint edit_object (GLuint n);
		/** Dont edit any object */
		void dont_edit ();
		/** Dont edit the edited face */
		void dont_edit_face ();

		/* Basic operations */
		
		/** \brief Move selected objects to determined position
 		 * \param pos : new position of the center of mass */ 
		void move (Vertex3D pos);	
		/** \brief Scale selected objects 
 		 * \param factor : scale factor 
 		 * \param axis : scale the object restricted to axis */
		void scale (GLdouble factor, TAxis axis);
		/** \brief Rotate selected objects
 		 *  \param degree : degrees to rotate
 		 *  \param axis : axis to rotate around */
		void rotate (GLdouble degree, TAxis axis); 
		/** \brief Extrude the edited object
 		 * 	\param t : one of the triangles of the face to extrude 
 		 * 	\param dist : distance to extrude, sign means direction */
		void extrude (Triangle *t, GLdouble dist);	
		/** \brief Merge two objects
		*	\param a: descriptor of the first object
		*	\param b: descriptor of the second object*/
		void merge(GLuint, GLuint);

		/* Insert basic figures */
		
		/** \brief Insert a plane
 		 * \param x : length
 		 * \param y : anchor */
		void insert_plane (GLdouble x, GLdouble y);
		/** \brief Insert a cube
 		 *	\param side : length of the sides */ 
		void insert_cube (GLdouble side);
		/** \brief Insert sphere
 		 * \param radius : radius of the sphere */
		void insert_sphere (GLdouble radius);
		/** \brief Insert pyramid
 		 * \param base_side_n : number of sides of the base
 		 * \param base_side : length of base sides
 		 * \param heigth : heigth of the pyramid */
		void insert_pyramid (GLuint base_side_n, GLdouble base_side, GLdouble height);
		/** \brief Insert monkey */
		void insert_monkey ();
		/** \brief Insert teapot */
		void insert_teapot ();
		

		/** Draw scene */
		void draw ();

};

#endif

